import threading
import logging
import time
import datetime
import webbrowser
import subprocess
import os
import platform

logger = logging.getLogger(__name__)


class IPCDeployer:
    def __init__(self, main_window):
        self.main_window = main_window

    def batch_deploy_ipc(self):
        """批量部署选中的工控机"""
        logger.info("尝试批量部署工控机...")
        selected_servers = []
        for item in self.main_window.server_connection.server_table.get_children():
            values = self.main_window.server_connection.server_table.item(item, "values")
            if values[0] == "√" and values[5] in ["已连接", "已连接(develop)", "已连接(缓存)"]:
                ip = values[1]
                if ip in self.main_window.server_connection.ssh_sessions:
                    selected_servers.append({
                        'ip': ip,
                        'item_id': item
                    })

        if not selected_servers:
            self.main_window.show_message("请选择已连接的服务器")
            logger.warning("批量部署：没有选中的已连接服务器")
            return

        # 显示开始部署信息
        self.main_window.show_message(f"开始批量部署 {len(selected_servers)} 台服务器...")
        logger.info(f"开始批量部署 {len(selected_servers)} 台服务器")

        # 更新服务器状态为部署中
        for server in selected_servers:
            self.main_window.server_connection.update_server_status(server['item_id'], "部署中...", 8)
            logger.info(f"设置服务器 {server['ip']} 状态为 '部署中...' ")

        # 创建线程池执行部署
        threads = []
        for server in selected_servers:
            thread = threading.Thread(
                target=self.deploy_ipc,
                args=(server['ip'], server['item_id']),
                name=f"Deploy-{server['ip']}"
            )
            print(f"server['ip']:{server['ip']}")
            logger.info(f"为服务器 {server['ip']} 启动部署线程")
            thread.daemon = True
            threads.append(thread)
            thread.start()

        self.main_window.show_message(f"已启动 {len(selected_servers)} 个部署线程")
        logger.info(f"已启动 {len(selected_servers)} 个部署线程")

    def deploy_ipc(self, ip, item_id):
        """执行单个工控机部署"""
        logger.info(f"开始在 {ip} 上执行工控机部署")
        
        # 在终端显示开始部署信息
        self.main_window.server_connection.append_to_terminal(ip, f"\n=== 开始部署工控机 ===\n")
        self.main_window.server_connection.append_to_terminal(ip, f"部署时间: {time.strftime('%Y-%m-%d %H:%M:%S')}\n")
        
        try:
            # 获取服务器配置信息
            self.main_window.server_connection.append_to_terminal(ip, "步骤1: 读取服务器配置信息...\n")
            server_info = self._read_configuration_data(self.main_window.server_file_path.get(), ip)
            logger.info(f"在 {ip} 上获取服务器配置信息: {server_info}")
            self.main_window.server_connection.append_to_terminal(ip, f"配置信息读取成功: {server_info}\n")

            # 创建部署器
            self.main_window.server_connection.append_to_terminal(ip, "步骤2: 初始化部署器...\n")
            deployer = ActualIPCDeployer({
                'ssh': self.main_window.server_connection.ssh_sessions[ip]['ssh'],
                'shell': self.main_window.server_connection.ssh_sessions[ip]['shell'],
                'ip': ip,
                'item_id': item_id
            })
            # 设置主窗口引用，用于终端输出
            deployer.set_main_window(self.main_window)
            logger.info(f"已为 {ip} 创建部署器")
            self.main_window.server_connection.append_to_terminal(ip, "部署器初始化成功\n")

            # 获取当前部署选项状态
            deploy_vars = {
                'configure_hostname': self.main_window.deploy_vars['configure_hostname'].get(),
                'configure_hosts': self.main_window.deploy_vars['configure_hosts'].get(),
                'configure_dns': self.main_window.deploy_vars['configure_dns'].get(),
                'sync_time': self.main_window.deploy_vars['sync_time'].get(),
                'load_image': self.main_window.deploy_vars['load_image'].get(),
                'register_node': self.main_window.deploy_vars['register_node'].get()
            }
            
            # 如果启用了同步时间，获取时间值
            if deploy_vars['sync_time']:
                deploy_vars['sync_time'] = self.main_window.sync_time_value.get()
                deploy_vars['network_interface'] = self.main_window.network_interface.get()
            
            # 在终端显示部署选项
            self.main_window.server_connection.append_to_terminal(ip, "步骤3: 检查部署选项...\n")
            enabled_options = []
            for option, enabled in deploy_vars.items():
                if enabled:
                    option_name = {
                        'configure_hostname': '配置主机名',
                        'configure_hosts': '配置hosts文件',
                        'configure_dns': '配置DNS解析',
                        'sync_time': '同步时间',
                        'load_image': '加载镜像',
                        'register_node': '注册节点'
                    }.get(option, option)
                    enabled_options.append(option_name)
            
            if enabled_options:
                self.main_window.server_connection.append_to_terminal(ip, f"启用的部署选项: {', '.join(enabled_options)}\n")
            else:
                self.main_window.server_connection.append_to_terminal(ip, "警告: 没有启用任何部署选项\n")
            
            logger.info(f"部署选项 for {ip}: {deploy_vars}")
            
            # 执行部署
            self.main_window.server_connection.append_to_terminal(ip, "步骤4: 开始执行部署...\n")
            self.main_window.server_connection.append_to_terminal(ip, f"部署配置: {server_info}\n")
            success, message = deployer.deploy(server_info, deploy_vars)

            # 更新状态
            status = "部署成功" if success else "部署失败"
            self.main_window.server_connection.update_server_status(item_id, status, 8)
            self.main_window.show_message(f"{ip}: {message}")
            
            # 在终端显示部署结果
            if success:
                self.main_window.server_connection.append_to_terminal(ip, f"\n=== 部署成功 ===\n")
                self.main_window.server_connection.append_to_terminal(ip, f"完成时间: {time.strftime('%Y-%m-%d %H:%M:%S')}\n")
                self.main_window.server_connection.append_to_terminal(ip, f"部署结果: {message}\n")
            else:
                self.main_window.server_connection.append_to_terminal(ip, f"\n=== 部署失败 ===\n")
                self.main_window.server_connection.append_to_terminal(ip, f"错误信息: {message}\n")
            
            # 强制更新终端显示
            self.main_window.root.update_idletasks()
            logger.info(f"工控机部署完成 for {ip}: {status} - {message}")

        except Exception as e:
            error_msg = f"部署失败: {str(e)}"
            self.main_window.show_message(error_msg)
            self.main_window.server_connection.update_server_status(item_id, f"部署失败: {str(e)[:20]}...", 8)
            
            # 在终端显示错误信息
            self.main_window.server_connection.append_to_terminal(ip, f"\n=== 部署异常 ===\n")
            self.main_window.server_connection.append_to_terminal(ip, f"错误信息: {str(e)}\n")
            self.main_window.server_connection.append_to_terminal(ip, f"异常时间: {time.strftime('%Y-%m-%d %H:%M:%S')}\n")
            
            logger.error(f"在 {ip} 上执行工控机部署失败: {e}", exc_info=True)
            print(f"部署失败: {str(e)}")

    def _read_configuration_data(self, server_file_path, ip):
        """读取服务器配置信息"""
        try:
            import openpyxl
            
            # 读取Excel文件
            workbook = openpyxl.load_workbook(server_file_path)
            sheet = workbook.active
            
            # 获取表头信息，用于确定列索引
            headers = []
            for cell in sheet[1]:
                headers.append(cell.value)

            # print(f'表格的表头为：{headers}')
            
            # 查找对应IP的配置信息
            for row in sheet.iter_rows(min_row=2, values_only=True):
                print(f'行数据为：{row}')
                if len(row) > 1 and row[0] == ip:  # IP在第二列
                    # 构建配置信息字典
                    config = {
                        'ip': ip,
                        'hostname': '',
                        'primary_ipc_ip': '',
                        'backup_ipc_ip': '',
                        'virtual_ipc_ip': '',
                        'dedup_server_ip': '',
                        'username': 'root',
                        'password': '',
                        'description': ''
                    }
                    
                    # 根据表头映射数据
                    for i, header in enumerate(headers):
                        if i < len(row) and row[i]:
                            header_lower = str(header).lower() if header else ''
                            if '工控机主机名' in header_lower or 'hostname' in header_lower:
                                config['hostname'] = str(row[i])
                            elif '主工控机IP' in header_lower or 'primary' in header_lower:
                                config['primary_ipc_ip'] = str(row[i])
                            elif '备工控机IP' in header_lower or 'backup' in header_lower:
                                config['backup_ipc_ip'] = str(row[i])
                            elif '工控机虚拟IP' in header_lower or 'virtual' in header_lower or 'vip' in header_lower:
                                config['virtual_ipc_ip'] = str(row[i])
                            elif '去重服务器IP' in header_lower or 'dedup' in header_lower:
                                config['dedup_server_ip'] = str(row[i])
                            elif '用户名' in header_lower or 'username' in header_lower:
                                config['username'] = str(row[i])
                            elif '密码' in header_lower or 'password' in header_lower:
                                config['password'] = str(row[i])
                            elif '描述' in header_lower or 'description' in header_lower:
                                config['description'] = str(row[i])
                    
                    # 如果没有主机名，生成默认主机名
                    if not config['hostname']:
                        config['hostname'] = f"ipc-{ip.replace('.', '-')}"
                    
                    print(f'主机信息：{config}')
                    
                    return config
            
            # 如果没找到，返回默认配置
            return {
                'hostname': f"ipc-{ip.replace('.', '-')}",
                'ip': ip,
                'primary_ipc_ip': '',
                'backup_ipc_ip': '',
                'virtual_ipc_ip': '',
                'dedup_server_ip': '',
                'username': 'root',
                'password': '',
                'description': '默认配置'
            }
            
        except Exception as e:
            logger.error(f"读取配置文件失败: {e}")
            # 返回默认配置
            return {
                'hostname': f"ipc-{ip.replace('.', '-')}",
                'ip': ip,
                'primary_ipc_ip': '',
                'backup_ipc_ip': '',
                'virtual_ipc_ip': '',
                'dedup_server_ip': '',
                'username': 'root',
                'password': '',
                'description': '配置读取失败，使用默认值'
            }

    def open_huawei_cloud(self):
        """打开华为云控制台并配置hosts"""
        try:
            # 华为云控制台URL
            huawei_cloud_url = "https://console.ecloud.chinaetc.org/"
            
            # 需要添加到hosts的解析记录
            hosts_entries = [
                "console.ecloud.chinaetc.org",
                "auth.ecloud.chinaetc.org",
                "iam.ecloud.chinaetc.org"
            ]
            
            # 检查并更新Windows hosts文件
            self._update_windows_hosts(hosts_entries)
            
            # 打开浏览器
            webbrowser.open(huawei_cloud_url)
            self.main_window.show_message("华为云控制台已打开")
            logger.info("华为云控制台已打开")
            
        except Exception as e:
            error_msg = f"打开华为云控制台失败: {str(e)}"
            self.main_window.show_message(error_msg)
            logger.error(error_msg)

    def _update_windows_hosts(self, hosts_entries):
        """更新Windows hosts文件"""
        try:
            hosts_file = r"C:\Windows\System32\drivers\etc\hosts"
            
            # 读取现有hosts文件
            try:
                with open(hosts_file, 'r', encoding='utf-8') as f:
                    existing_content = f.read()
            except:
                with open(hosts_file, 'r', encoding='gbk') as f:
                    existing_content = f.read()
            
            # 检查是否需要添加新记录
            new_entries = []
            for entry in hosts_entries:
                if entry not in existing_content:
                    # 这里可以添加具体的IP解析，暂时使用注释
                    new_entries.append(f"# {entry} - 华为云解析")
            
            if new_entries:
                # 尝试以管理员权限写入hosts文件
                try:
                    with open(hosts_file, 'a', encoding='utf-8') as f:
                        f.write('\n# 华为云解析记录\n')
                        for entry in new_entries:
                            f.write(f"{entry}\n")
                    logger.info("hosts文件更新成功")
                except PermissionError:
                    # 如果权限不足，尝试使用管理员权限
                    self._run_as_admin_hosts_update(new_entries)
            else:
                logger.info("hosts文件已包含所需记录")
                
        except Exception as e:
            logger.warning(f"更新hosts文件失败: {e}")

    def _run_as_admin_hosts_update(self, new_entries):
        """以管理员权限更新hosts文件"""
        try:
            # 创建临时脚本
            script_content = f'''
import sys
hosts_file = r"C:\\Windows\\System32\\drivers\\etc\\hosts"
new_entries = {new_entries}

try:
    with open(hosts_file, 'a', encoding='utf-8') as f:
        f.write('\\n# 华为云解析记录\\n')
        for entry in new_entries:
            f.write(f"{{entry}}\\n")
    print("hosts文件更新成功")
except Exception as e:
    print(f"更新失败: {{e}}")
'''
            
            # 写入临时脚本文件
            temp_script = "temp_hosts_update.py"
            with open(temp_script, 'w', encoding='utf-8') as f:
                f.write(script_content)
            
            # 尝试以管理员权限运行
            if platform.system() == "Windows":
                subprocess.run([
                    "powershell", "-Command", 
                    f"Start-Process python -ArgumentList '{temp_script}' -Verb RunAs"
                ], check=False)
            
            # 清理临时文件
            try:
                os.remove(temp_script)
            except:
                pass
                
        except Exception as e:
            logger.warning(f"管理员权限更新hosts失败: {e}")


class ActualIPCDeployer:
    """实际的IPC部署器"""
    
    def __init__(self, connection_info):
        self.ssh = connection_info['ssh']
        self.shell = connection_info['shell']
        self.ip = connection_info['ip']
        self.item_id = connection_info['item_id']
        self.main_window = None
        self.server_arch = None
        
    def set_main_window(self, main_window):
        """设置主窗口引用"""
        self.main_window = main_window
        
    def _append_to_terminal(self, message):
        """向终端添加消息"""
        if self.main_window:
            self.main_window.server_connection.append_to_terminal(self.ip, message)
            
    def _execute_command(self, command, description="", timeout=10):
        """执行SSH命令"""
        try:
            if description:
                self._append_to_terminal(f"执行: {description}\n")
                
            self._append_to_terminal(f"命令: {command}\n")
            
            # 发送命令
            self.shell.send(command + '\n')
            time.sleep(2)
            
            # 读取输出
            output = ""
            start_time = time.time()
            while time.time() - start_time < timeout:
                if self.shell.recv_ready():
                    data = self.shell.recv(4096).decode('utf-8', errors='ignore')
                    output += data
                    if data.endswith('$ ') or data.endswith('# ') or data.endswith('> '):
                        break
                time.sleep(0.1)
                
            self._append_to_terminal(f"输出: {output}\n")
            return True, output.strip()
            
        except Exception as e:
            error_msg = f"命令执行失败: {str(e)}\n"
            self._append_to_terminal(error_msg)
            logger.error(f"在 {self.ip} 上执行命令失败: {e}")
            return False, str(e)

    def _get_server_architecture(self):
        """获取服务器架构"""
        try:
            self._append_to_terminal("检测服务器架构...\n")
            success, output = self._execute_command("uname -m", "获取系统架构")
            
            if success:
                arch = output.lower().strip()
                if 'x86_64' in arch or 'amd64' in arch:
                    self.server_arch = 'x86'
                    self._append_to_terminal(f"检测到x86架构: {arch}\n")
                elif 'arm' in arch or 'aarch64' in arch:
                    self.server_arch = 'arm'
                    self._append_to_terminal(f"检测到ARM架构: {arch}\n")
                else:
                    self.server_arch = 'unknown'
                    self._append_to_terminal(f"未知架构: {arch}\n")
                return True
            else:
                self.server_arch = 'unknown'
                return False
                
        except Exception as e:
            self._append_to_terminal(f"架构检测失败: {str(e)}\n")
            self.server_arch = 'unknown'
            return False

    def _configure_hostname(self, hostname):
        """配置主机名"""
        try:
            self._append_to_terminal(f"配置主机名为: {hostname}\n")
            
            if self.server_arch == 'x86':
                # x86架构使用hostnamectl命令
                success, output = self._execute_command(
                    f"hostnamectl set-hostname {hostname}", 
                    "使用hostnamectl设置主机名"
                )
            else:
                # ARM架构或其他架构直接写入/etc/hostname文件
                success1, output1 = self._execute_command(
                    "echo '' > /etc/hostname", 
                    "清空/etc/hostname文件"
                )
                success2, output2 = self._execute_command(
                    f"echo '{hostname}' > /etc/hostname", 
                    "写入新主机名到/etc/hostname"
                )
                success = success1 and success2
                output = f"{output1}\n{output2}"
            
            if success:
                # 验证主机名设置
                verify_success, verify_output = self._execute_command(
                    "hostname", 
                    "验证主机名设置"
                )
                if verify_success and hostname in verify_output:
                    self._append_to_terminal("✓ 主机名配置成功\n")
                    return True
                else:
                    self._append_to_terminal("⚠ 主机名设置可能需要重启生效\n")
                    return True
            else:
                self._append_to_terminal("✗ 主机名配置失败\n")
                return False
                
        except Exception as e:
            self._append_to_terminal(f"主机名配置异常: {str(e)}\n")
            return False

    def _generate_host_info(self, server_info):
        """根据配置信息生成主机信息"""
        try:
            hostname = server_info.get('hostname', '')
            if not hostname:
                return {}
            
            # 生成主工控机主机名 (去掉最后1个字符 + 1)
            primary_hostname = hostname[:-1] + '1' if len(hostname) > 0 else 'ipc01'
            
            # 生成备工控机主机名 (去掉最后1个字符 + 2)  
            backup_hostname = hostname[:-1] + '2' if len(hostname) > 0 else 'ipc02'
            
            # 生成虚拟主机名 (去掉最后2个字符 + vip)
            virtual_hostname = hostname[:-2] + 'vip' if len(hostname) > 1 else 'ipcvip'
            
            # 去重服务器主机名固定
            dedup_hostname = 'www.gantryserver1.com'
            
            host_info = {
                'primary': {
                    'ip': server_info.get('primary_ipc_ip', ''),
                    'hostname': primary_hostname
                },
                'backup': {
                    'ip': server_info.get('backup_ipc_ip', ''),
                    'hostname': backup_hostname
                },
                'virtual': {
                    'ip': server_info.get('virtual_ipc_ip', ''),
                    'hostname': virtual_hostname
                },
                'dedup': {
                    'ip': server_info.get('dedup_server_ip', ''),
                    'hostname': dedup_hostname
                }
            }
            
            self._append_to_terminal("生成的主机信息:\n")
            for key, info in host_info.items():
                if info['ip']:
                    self._append_to_terminal(f"  {key}: {info['ip']} {info['hostname']}\n")
            
            return host_info
            
        except Exception as e:
            self._append_to_terminal(f"生成主机信息失败: {str(e)}\n")
            return {}

    def _configure_hosts_file(self, host_info):
        """配置系统hosts文件"""
        try:
            self._append_to_terminal("配置系统hosts文件...\n")
            
            # 首先读取现有的hosts文件
            success, current_hosts = self._execute_command(
                "cat /etc/hosts", 
                "读取当前hosts文件"
            )
            
            if not success:
                self._append_to_terminal("✗ 无法读取hosts文件\n")
                return False
            
            # 检查并添加hosts条目
            added_count = 0
            for host_type, info in host_info.items():
                if info['ip'] and info['hostname']:
                    # 检查是否已存在该IP的记录
                    if info['ip'] not in current_hosts:
                        # 添加hosts条目
                        hosts_entry = f"{info['ip']} {info['hostname']}"
                        success, output = self._execute_command(
                            f"echo '{hosts_entry}' >> /etc/hosts", 
                            f"添加{host_type}主机记录"
                        )
                        if success:
                            added_count += 1
                            self._append_to_terminal(f"✓ 已添加: {hosts_entry}\n")
                        else:
                            self._append_to_terminal(f"✗ 添加失败: {hosts_entry}\n")
                    else:
                        self._append_to_terminal(f"⚠ 已存在: {info['ip']} (跳过)\n")
            
            if added_count > 0:
                self._append_to_terminal(f"✓ hosts文件配置完成，添加了{added_count}条记录\n")
                return True
            else:
                self._append_to_terminal("⚠ 所有记录已存在，无需添加\n")
                return True
                
        except Exception as e:
            self._append_to_terminal(f"配置hosts文件异常: {str(e)}\n")
            return False

    def _configure_dns_resolv(self):
        """配置DNS解析"""
        try:
            self._append_to_terminal("配置DNS解析...\n")
            
            # 需要添加的DNS服务器
            dns_servers = [
                "nameserver 10.254.6.199",
                "nameserver 10.254.6.200"
            ]
            
            # 读取现有的resolv.conf文件
            success, current_resolv = self._execute_command(
                "cat /etc/resolv.conf", 
                "读取当前DNS配置"
            )
            
            if not success:
                current_resolv = ""
            
            # 检查并添加DNS服务器
            added_count = 0
            for dns_entry in dns_servers:
                if dns_entry not in current_resolv:
                    success, output = self._execute_command(
                        f"echo '{dns_entry}' >> /etc/resolv.conf", 
                        f"添加DNS服务器"
                    )
                    if success:
                        added_count += 1
                        self._append_to_terminal(f"✓ 已添加: {dns_entry}\n")
                    else:
                        self._append_to_terminal(f"✗ 添加失败: {dns_entry}\n")
                else:
                    self._append_to_terminal(f"⚠ 已存在: {dns_entry}\n")
            
            if added_count > 0:
                self._append_to_terminal(f"✓ DNS配置完成，添加了{added_count}条记录\n")
            else:
                self._append_to_terminal("⚠ DNS记录已存在，无需添加\n")
            
            return True
            
        except Exception as e:
            self._append_to_terminal(f"配置DNS解析异常: {str(e)}\n")
            return False

    def _sync_system_time(self):
        """同步系统时间"""
        try:
            self._append_to_terminal("同步系统时间...\n")
            
            # 获取本机Windows系统时间
            current_time = datetime.datetime.now()
            time_str = current_time.strftime("%Y-%m-%d %H:%M:%S")
            
            self._append_to_terminal(f"本机时间: {time_str}\n")
            
            # 设置远程Linux服务器时间
            success, output = self._execute_command(
                f'date -s "{time_str}"', 
                "设置系统时间"
            )
            
            if success:
                # 验证时间设置
                verify_success, verify_output = self._execute_command(
                    "date", 
                    "验证系统时间"
                )
                if verify_success:
                    self._append_to_terminal(f"✓ 时间同步成功，当前时间: {verify_output}\n")
                    return True
                else:
                    self._append_to_terminal("⚠ 时间设置成功但验证失败\n")
                    return True
            else:
                self._append_to_terminal("✗ 时间同步失败\n")
                return False
                
        except Exception as e:
            self._append_to_terminal(f"时间同步异常: {str(e)}\n")
            return False
    
    def deploy(self, server_info, deploy_vars):
        """执行部署"""
        try:
            self._append_to_terminal("=== 开始执行部署任务 ===\n")
            
            success_count = 0
            total_tasks = 0
            
            # 首先获取服务器架构
            self._get_server_architecture()
            
            # 配置主机名
            if deploy_vars.get('configure_hostname'):
                total_tasks += 1
                self._append_to_terminal("任务1: 配置工控机主机名\n")
                if self._configure_hostname(server_info['hostname']):
                    success_count += 1
            
            # 配置hosts文件
            if deploy_vars.get('configure_hosts'):
                total_tasks += 1
                self._append_to_terminal("任务2: 配置系统hosts文件\n")
                host_info = self._generate_host_info(server_info)
                if host_info and self._configure_hosts_file(host_info):
                    success_count += 1
            
            # 配置DNS
            if deploy_vars.get('configure_dns'):
                total_tasks += 1
                self._append_to_terminal("任务3: 配置DNS解析\n")
                if self._configure_dns_resolv():
                    success_count += 1
            
            # 同步时间
            if deploy_vars.get('sync_time'):
                total_tasks += 1
                self._append_to_terminal("任务4: 同步系统时间\n")
                if self._sync_system_time():
                    success_count += 1
            
            # 加载镜像
            if deploy_vars.get('load_image'):
                total_tasks += 1
                self._append_to_terminal("任务5: 加载Docker镜像\n")
                success, output = self._execute_command(
                    "docker images", 
                    "检查Docker镜像"
                )
                if success:
                    success_count += 1
                    self._append_to_terminal("✓ 镜像检查成功\n")
                else:
                    self._append_to_terminal("✗ 镜像操作失败\n")
            
            # 注册节点
            if deploy_vars.get('register_node'):
                total_tasks += 1
                self._append_to_terminal("任务6: 注册集群节点\n")
                success, output = self._execute_command(
                    "kubectl get nodes", 
                    "检查集群节点状态"
                )
                if success:
                    success_count += 1
                    self._append_to_terminal("✓ 节点注册检查成功\n")
                else:
                    self._append_to_terminal("✗ 节点注册失败\n")
            
            # 计算成功率
            if total_tasks > 0:
                success_rate = success_count / total_tasks
                if success_rate >= 0.8:  # 80%以上成功率认为部署成功
                    return True, f"部署成功 ({success_count}/{total_tasks} 任务完成)"
                else:
                    return False, f"部署部分失败 ({success_count}/{total_tasks} 任务完成)"
            else:
                return False, "没有启用任何部署任务"
                
        except Exception as e:
            error_msg = f"部署过程异常: {str(e)}"
            self._append_to_terminal(f"异常: {error_msg}\n")
            logger.error(f"部署异常: {e}", exc_info=True)
            return False, error_msg